package com.quectel.cms.controller.partybuildingsurvey;


import cn.hutool.core.lang.func.LambdaUtil;
import com.quectel.business.common.util.sys.SysCodeUtils;
import com.quectel.cms.controller.BaseController;
import com.quectel.constant.core.partybuilding.PartySurveyConstants;
import com.quectel.constant.global.SystemConstants;
import com.quectel.util.aspect.log.annotation.Log;
import com.quectel.constant.global.annotation.RequirePermissions;
import com.quectel.constant.sys.SysCodeKeyConstants;
import com.quectel.core.module.partybuildingsurvey.dto.*;
import com.quectel.core.module.partybuildingsurvey.service.PartySurveyPersonAnswerService;
import com.quectel.core.module.partybuildingsurvey.service.PartySurveyPersonBindingService;
import com.quectel.core.module.partybuildingsurvey.service.PartySurveyPersonRecordService;
import com.quectel.core.module.partybuildingsurvey.service.PartySurveyService;
import com.quectel.util.common.*;
import com.quectel.util.kit.PageFetchKit;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author bob
 * @email bob.yu@quectel.com
 * @date 2023/05/24 11:38
 */
@RestController
@RequestMapping("partySurveyPersonBinding")
@Tag(name = "PartySurveyPersonBindingController", description = "问卷调查人员绑定关系相关api")
public class PartySurveyPersonBindingController extends BaseController {

    @DubboReference
    private PartySurveyPersonBindingService partySurveyPersonBindingService;
    @DubboReference
    private PartySurveyPersonRecordService partySurveyPersonRecordService;
    @DubboReference
    private PartySurveyService partySurveyService;
    @DubboReference
    private PartySurveyPersonAnswerService partySurveyPersonAnswerService;

    /**
     * 导出记录
     */
    @GetMapping("exportExcel")
    @RequirePermissions(values = {"partySurvey:exportExcel", "partySurveyPersonBinding:exportExcel"})
    @Operation(summary = "导出问卷调查记录")
    @Log(express = "导出问卷调查记录")
    public void exportExcel(@RequestParam Map<String, Object> params, HttpServletResponse hresp) {
        Request request = Request.configParamsNotPage(params);

        super.fillAuthorityData(params);
        Long partySurveyId = request.getLong(LambdaUtil.getFieldName(PartySurveyPersonBindingDto::getPartySurveyId));
        PartySurveyDto partySurveyDto = partySurveyService.selectCacheById(partySurveyId);


        List<PartySurveyPersonBindingDto> result = PageFetchKit.fetchAll(r -> partySurveyPersonBindingService.queryList(r), request.getParams());

        String[] headers = new String[]{"问卷名称", "所属党组织", "参加人", "联系电话", "是否参加", "提交时间"};

        List<String> list = new ArrayList<>(Arrays.asList(headers));

        List<PartySurveyQuestionDto> bindQuestion = partySurveyDto.getBindQuestion();
        if (CollectionUtils.isNotEmpty(bindQuestion)) {
            bindQuestion.stream().sorted(Comparator.comparing(PartySurveyQuestionDto::getSort)).collect(Collectors.toList()).forEach(partySurveyQuestionDto -> {
                list.add("Q" + partySurveyQuestionDto.getSort() + "_" + partySurveyQuestionDto.getName());
            });
        }
        Map<Integer, PartySurveyQuestionDto> questionMap = bindQuestion.stream().collect(Collectors.toMap(PartySurveyQuestionDto::getSort, Function.identity(), (key1, key2) -> key2));

        List<String[]> dataList = new ArrayList<>();
        for (PartySurveyPersonBindingDto data : result) {
            List<PartySurveyPersonRecordDto> partySurveyPersonRecordDtoList = partySurveyPersonRecordService.selectBySurveyIdAndPersonId(data.getPartySurveyId(), data.getPersonId());
            for (PartySurveyPersonRecordDto surveyPersonRecordDto : partySurveyPersonRecordDtoList) {
                String[] item = new String[list.size()];
                item[0] = data.getPartySurveyName();
                item[1] = data.getPartyName();
                if (SystemConstants.YES.equals(surveyPersonRecordDto.getAnonymous())) {
                    item[2] = "匿名";
                    item[3] = "";
                } else {
                    item[2] = data.getPersonName();
                    item[3] = data.getPersonMobile();
                }
                item[4] = SysCodeUtils.easyToGetName(SysCodeKeyConstants.YES_OR_NOT, String.valueOf(data.getParticipateStatus()));
                item[5] = DateUtils.format(data.getParticipateTime(), DateUtils.FormatType.COMMON);

                //查询答题结果
                List<PartySurveyPersonAnswerDto> partySurveyPersonAnswerDtos = partySurveyPersonAnswerService.selectByRecordId(surveyPersonRecordDto.getId());

                if (CollectionUtils.isNotEmpty(partySurveyPersonAnswerDtos)) {
                    Map<Long, PartySurveyPersonAnswerDto> answerDtoMap = partySurveyPersonAnswerDtos.stream().collect(Collectors.toMap(PartySurveyPersonAnswerDto::getQuestionId, Function.identity(), (key1, key2) -> key2));
                    for (int i = 6; i < list.size(); i++) {
                        //sort从1开始
                        PartySurveyQuestionDto partySurveyQuestionDto = questionMap.get(i - 5);
                        if (partySurveyQuestionDto == null) {
                            continue;
                        }
                        PartySurveyPersonAnswerDto partySurveyPersonAnswerDto = answerDtoMap.get(partySurveyQuestionDto.getId());
                        if (partySurveyQuestionDto.getType().equals(PartySurveyConstants.QuestionType.SINGLE_CHOICE.getType())
                                || partySurveyQuestionDto.getType().equals(PartySurveyConstants.QuestionType.MULTIPLE_CHOICE.getType())
                                || partySurveyQuestionDto.getType().equals(PartySurveyConstants.QuestionType.PIC_SINGLE_CHOICE.getType())
                                || partySurveyQuestionDto.getType().equals(PartySurveyConstants.QuestionType.PIC_MULTIPLE_CHOICE.getType())
                        ) {
                            List<Long> choiceAnswer = partySurveyPersonAnswerDto.getChoiceAnswer();
                            if(CollectionUtils.isNotEmpty(choiceAnswer)){
                                Map<Long, PartySurveyAnswerDto> collect = partySurveyQuestionDto.getBindAnswer().stream().collect(Collectors.toMap(PartySurveyAnswerDto::getId, Function.identity(), (key1, key2) -> key2));

                                StringBuilder stringBuilder = new StringBuilder();
                                for (Long aLong : choiceAnswer) {
                                    PartySurveyAnswerDto partySurveyAnswerDto = collect.get(aLong);
                                    if(partySurveyAnswerDto!=null){
                                        stringBuilder.append(partySurveyAnswerDto.getContent()).append("|");
                                    }
                                }
                                item[i] = stringBuilder.substring(0,stringBuilder.length()-1);
                            }else{
                                item[i] = "";
                            }

                        }
                        if (partySurveyQuestionDto.getType().equals(PartySurveyConstants.QuestionType.BLANK.getType())) {
                            Map<Long, String> blankAnswer = partySurveyPersonAnswerDto.getBlankAnswer();
                            StringBuilder stringBuilder = new StringBuilder();
                            if(blankAnswer!=null){
                                blankAnswer.forEach((aLong, s) -> {
                                    stringBuilder.append(s).append("|");
                                });
                                item[i] = stringBuilder.substring(0,stringBuilder.length()-1);
                            }else{
                                item[i] = "";
                            }

                        }
                        if (partySurveyQuestionDto.getType().equals(PartySurveyConstants.QuestionType.EVALUATE.getType())) {
                            List<PartySurveyAnswerDto> bindAnswer = partySurveyQuestionDto.getBindAnswer();
                            Map<Long, Double> evaluateAnswer = partySurveyPersonAnswerDto.getEvaluateAnswer();
                            StringBuilder stringBuilder = new StringBuilder();
                            if(evaluateAnswer!=null){
                                evaluateAnswer.forEach((aLong, s) -> {
                                    stringBuilder.append(s).append("|");
                                });
                                item[i] = stringBuilder.substring(0,stringBuilder.length()-1);
                            }else{
                                item[i] = "";
                            }
                        }
                    }
                }
                dataList.add(item);
            }

        }
        POIUtils.exportExcel(hresp, "问卷调查记录", list.toArray(new String[]{}), dataList, "问卷调查记录");

    }


    /**
     * 分页查询
     *
     * @param pageNo
     * @param pageSize
     * @return
     */
    @GetMapping("list")
    @RequirePermissions(values = {"partySurveyPersonBinding:list", "partySurvey:statistics"})
    @Operation(summary = "分页获取问卷调查人员绑定关系列表")
    public Response<Page<PartySurveyPersonBindingDto>> list(
            @Parameter(description = "从1开始的页码数") @RequestParam Integer pageNo,
            @Parameter(description = "每页多少条") @RequestParam Integer pageSize
    ) {
        //查询列表数据
        Request request = Request.configParams(Request.parseParams(httpServletRequest));

        super.fillAuthorityData(request.getParams());
        int total = partySurveyPersonBindingService.queryTotal(request.getParams());

        List<PartySurveyPersonBindingDto> list = null;
        if (total > 0) {
            list = partySurveyPersonBindingService.queryList(request.getParams());
        } else {
            list = new ArrayList<>();
        }

        Page<PartySurveyPersonBindingDto> page = new Page<>(request.getPageNo(), request.getPageSize(), total, list);
        return Response.<Page<PartySurveyPersonBindingDto>>ok().wrap(page);
    }

    /**
     * 编辑查询反显
     *
     * @param id
     * @return
     */
    @GetMapping("infoForEdit/{id}")
    @RequirePermissions(values = "partySurveyPersonBinding:edit")
    @Operation(summary = "在编辑时根据id查询问卷调查人员绑定关系详情")
    public Response<PartySurveyPersonBindingDto> infoForEdit(@PathVariable("id") Long id) {

        Map<String, Object> params = new HashMap<>();
        super.fillAuthorityData(params);
        params.put(SystemConstants.ENTITY_ID_FLAG, String.valueOf(id));
        if (partySurveyPersonBindingService.queryTotal(params) <= 0) {
            return Response.error(SystemConstants.ILLEGAL_MSG);
        }

        PartySurveyPersonBindingDto partySurveyPersonBindingDto = partySurveyPersonBindingService.selectById(id);

        return Response.<PartySurveyPersonBindingDto>ok().wrap(partySurveyPersonBindingDto);
    }

    /**
     * 详情
     *
     * @param id
     * @return
     */
    @GetMapping("info/{id}")
    @RequirePermissions(values = "partySurveyPersonBinding:info")
    @Operation(summary = "根据id查询问卷调查人员绑定关系的详情")
    public Response<PartySurveyPersonBindingDto> info(@PathVariable("id") Long id) {

        Map<String, Object> params = new HashMap<>();
        super.fillAuthorityData(params);
        params.put(SystemConstants.ENTITY_ID_FLAG, String.valueOf(id));
        if (partySurveyPersonBindingService.queryTotal(params) <= 0) {
            return Response.error(SystemConstants.ILLEGAL_MSG);
        }

        PartySurveyPersonBindingDto partySurveyPersonBindingDto = partySurveyPersonBindingService.selectById(id);


        return Response.<PartySurveyPersonBindingDto>ok().wrap(partySurveyPersonBindingDto);
    }

    /**
     * 保存
     *
     * @param partySurveyPersonBindingDto
     * @return
     */
    @PostMapping("save")
    @RequirePermissions(values = "partySurveyPersonBinding:edit")
    @Operation(summary = "新增问卷调查人员绑定关系")
    public Response<Object> save(@RequestBody @Validated PartySurveyPersonBindingDto partySurveyPersonBindingDto) {

        //填充基础数据
        fillSaveCommonData(partySurveyPersonBindingDto);

        partySurveyPersonBindingService.save(partySurveyPersonBindingDto);

        return Response.ok();
    }


    /**
     * 修改
     *
     * @param partySurveyPersonBindingDto
     * @return
     */
    @PostMapping("update")
    @RequirePermissions(values = "partySurveyPersonBinding:edit")
    @Operation(summary = "根据id修改问卷调查人员绑定关系")
    public Response<Object> update(@RequestBody @Validated PartySurveyPersonBindingDto partySurveyPersonBindingDto) {

        Map<String, Object> params = new HashMap<>();
        super.fillAuthorityData(params);
        params.put(SystemConstants.ENTITY_ID_FLAG, String.valueOf(partySurveyPersonBindingDto.getId()));
        if (partySurveyPersonBindingService.queryTotal(params) <= 0) {
            return Response.error(SystemConstants.ILLEGAL_MSG);
        }
        //填充基础数据
        fillEditCommonData(partySurveyPersonBindingDto);

        partySurveyPersonBindingService.updateById(partySurveyPersonBindingDto);

        return Response.ok();
    }

    /**
     * 批量删除
     *
     * @param ids
     * @return
     */
    @PostMapping("delete")
    @RequirePermissions(values = "partySurveyPersonBinding:delete")
    @Operation(summary = "根据多条记录id批量删除问卷调查人员绑定关系")
    public Response<Object> delete(@RequestBody Long[] ids) {

        Map<String, Object> params = new HashMap<>();
        super.fillAuthorityData(params);

        for (Long id : ids) {

            params.remove(SystemConstants.ENTITY_ID_FLAG);
            params.put(SystemConstants.ENTITY_ID_FLAG, String.valueOf(id));

            if (partySurveyPersonBindingService.queryTotal(params) <= 0) {
                return Response.error(SystemConstants.ILLEGAL_MSG);
            }
        }

        partySurveyPersonBindingService.deleteBatch(ids);

        return Response.ok();
    }
}
